const express = require('express');
const router = express.Router();
const fs = require('fs-extra');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
const { createLogger, logService } = require('../utils/logger');
const { spawn } = require('child_process');
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
dayjs.extend(utc);
dayjs.extend(timezone);
const CHINA_TZ = 'Asia/Shanghai';
function chinaNow(ts) { return dayjs(ts).tz(CHINA_TZ).format('YYYY-MM-DD HH:mm:ss'); }

// 创建日志记录器
const logger = createLogger('build-api');

// 获取项目根目录
const rootDir = path.resolve(__dirname, '../../..');

// 配置文件路径
const BUILD_CONFIG_FILE = path.join(__dirname, '../config/build-config.json');

// 确保配置文件存在
if (!fs.existsSync(BUILD_CONFIG_FILE)) {
  fs.writeJSONSync(BUILD_CONFIG_FILE, {
    defaultEnv: "production",
    skipSourcemap: true,
    minify: true,
    reportBundle: false,
    mode: "standard",
    extraParams: ""
  }, { spaces: 2 });
  logger.info('创建了新的构建配置文件');
}

/**
 * 读取构建配置
 */
function readBuildConfig() {
  try {
    return fs.readJSONSync(BUILD_CONFIG_FILE);
  } catch (error) {
    logger.error('读取构建配置文件失败:', error);
    return {
      defaultEnv: "production",
      skipSourcemap: true,
      minify: true,
      reportBundle: false,
      mode: "standard",
      extraParams: ""
    };
  }
}

/**
 * 保存构建配置
 */
function saveBuildConfig(config) {
  try {
    fs.writeJSONSync(BUILD_CONFIG_FILE, config, { spaces: 2 });
    return true;
  } catch (error) {
    logger.error('保存构建配置文件失败:', error);
    return false;
}
}

/**
 * 获取构建配置
 */
router.get('/config', (req, res) => {
  try {
    const config = readBuildConfig();
    
    res.json({
      code: 200,
      message: '获取构建配置成功',
      data: config
    });
  } catch (error) {
    logger.error('获取构建配置失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取构建配置失败',
      error: error.message
    });
  }
});

/**
 * 更新构建配置
 */
router.put('/config', (req, res) => {
  try {
    const currentConfig = readBuildConfig();
    const updatedConfig = {
      ...currentConfig,
      ...req.body
    };
    
    saveBuildConfig(updatedConfig);
    
    res.json({
      code: 200,
      message: '更新构建配置成功',
      data: updatedConfig
    });
  } catch (error) {
    logger.error('更新构建配置失败:', error);
    res.status(500).json({
      code: 500,
      message: '更新构建配置失败',
      error: error.message
    });
  }
});

/**
 * 获取可用应用列表
 */
router.get('/apps', (req, res) => {
  try {
    const appsDir = path.join(rootDir, 'apps');
    const apps = [];
    
    if (fs.existsSync(appsDir)) {
      const dirs = fs.readdirSync(appsDir, { withFileTypes: true })
        .filter(dirent => dirent.isDirectory())
        .map(dirent => dirent.name);
      
      for (const dir of dirs) {
        const appDir = path.join(appsDir, dir);
        const packageJsonPath = path.join(appDir, 'package.json');
        
        if (fs.existsSync(packageJsonPath)) {
          const packageJson = fs.readJSONSync(packageJsonPath);
          const distPath = path.join(appDir, 'dist');
          const hasBuilt = fs.existsSync(distPath);
          
          apps.push({
            name: dir,
            title: packageJson.name || dir,
            path: appDir,
            status: hasBuilt ? 'ready' : 'idle',
            lastBuild: hasBuilt ? chinaNow(fs.statSync(distPath).mtime) : null,
            buildSize: hasBuilt ? getFolderSize(distPath) : null
          });
        }
      }
    }
    
    res.json({
      code: 200,
      message: '获取应用列表成功',
      data: apps
    });
  } catch (error) {
    logger.error('获取应用列表失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取应用列表失败',
      error: error.message
    });
  }
});

/**
 * 构建应用
 */
router.post('/app/:appName', async (req, res) => {
  const { appName } = req.params;
  const options = req.body || {};
  
  // 检查应用是否存在
  const appPath = path.join(rootDir, 'apps', appName);
  if (!fs.existsSync(appPath)) {
    return res.status(400).json({
      code: 400,
      message: `应用 ${appName} 不存在`
    });
  }
  
  try {
    // 创建构建任务ID
    const buildId = uuidv4();
    
    // 获取Express应用实例
    const app = require('../server').app;
    // 获取构建WebSocket命名空间
    const buildNamespace = app.get('buildNamespace');
    
    // 发送构建开始事件
    if (buildNamespace) {
      buildNamespace.to(buildId).emit('buildStart', {
        buildId,
        appName,
        options,
        timestamp: chinaNow()
      });
    }
    
    // 异步执行构建，不阻塞响应
    res.json({
      code: 200,
      message: '构建任务已提交',
      data: {
        buildId,
        appName,
        status: 'pending'
      }
    });
    
    // 在后台执行构建
    executeBuild(appName, options, buildId, buildNamespace);
    
  } catch (error) {
    logger.error(`构建应用 ${appName} 失败:`, error);
    res.status(500).json({
      code: 500,
      message: '构建失败',
      error: error.message
    });
  }
});

/**
 * 获取构建状态
 */
router.get('/status/:buildId', (req, res) => {
  const { buildId } = req.params;
  
  // 这里应该查询构建任务状态
  // 目前简单模拟构建状态，实际应用中应该从数据库或缓存中获取
  
  // 模拟不同的构建状态
  const statuses = ['pending', 'in_progress', 'completed', 'failed'];
  const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
  
  // 模拟进度
  const progress = randomStatus === 'completed' ? 100 : 
                   randomStatus === 'failed' ? 50 : 
                   Math.floor(Math.random() * 100);
  
  res.json({
    code: 200,
    message: '获取构建状态成功',
    data: {
      buildId,
      status: randomStatus,
      progress,
      message: getBuildStatusMessage(randomStatus),
      timestamp: chinaNow()
    }
  });
});

/**
 * 获取构建状态消息
 */
function getBuildStatusMessage(status) {
  switch(status) {
    case 'pending': return '构建任务等待中';
    case 'in_progress': return '构建任务执行中';
    case 'completed': return '构建已完成';
    case 'failed': return '构建失败';
    default: return '未知状态';
  }
}

/**
 * 获取构建日志
 */
router.get('/logs', (req, res) => {
  try {
    const { app, limit = 100, type } = req.query;
    
    // 使用日志服务获取构建日志
    const logs = logService.getLogs({
      app,
      type,
      limit: parseInt(limit, 10),
      category: 'build'
    });
    
    res.json({
      code: 200,
      message: '获取构建日志成功',
      data: logs
    });
  } catch (error) {
    logger.error('获取构建日志失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取构建日志失败',
      error: error.message
    });
  }
});

/**
 * 清除构建日志
 */
router.delete('/logs', (req, res) => {
  try {
    const { app } = req.query;
    
    // 使用日志服务清除构建日志
    const success = logService.clearLogs({
      app,
      category: 'build'
    });
    
    if (success) {
      logger.info(app ? `清除应用 ${app} 的构建日志` : '清除所有构建日志');
    
    res.json({
      code: 200,
        message: app ? `清除应用 ${app} 的构建日志成功` : '清除所有构建日志成功'
    });
    } else {
      throw new Error('清除日志失败');
    }
  } catch (error) {
    logger.error('清除构建日志失败:', error);
    res.status(500).json({
      code: 500,
      message: '清除构建日志失败',
      error: error.message
    });
  }
});

/**
 * 执行构建
 */
async function executeBuild(appName, options, buildId, buildNamespace) {
  const buildConfig = readBuildConfig();
  const env = options.env || buildConfig.defaultEnv || 'production';
  const skipSourcemap = options.skipSourcemap !== undefined ? options.skipSourcemap : buildConfig.skipSourcemap;
  const minify = options.minify !== undefined ? options.minify : buildConfig.minify;
  
  logger.info(`开始构建应用 ${appName}`, { env, skipSourcemap, minify });
  
  if (buildNamespace) {
    buildNamespace.to(buildId).emit('buildLog', {
      buildId,
      appName,
      log: `开始构建应用 ${appName}，环境: ${env}`,
      level: 'info',
      timestamp: chinaNow()
    });
  }
  
  try {
    // 使用Node.js的exec而不是spawn，可能更可靠
    const { exec } = require('child_process');
    const appDir = path.join(rootDir, 'apps', appName);
    
    // 构建命令
    const buildCommand = `cd "${appDir}" && npx vite build`;
    
    logger.info(`执行构建命令: ${buildCommand}`);
    
    // 执行构建命令
    const buildProcess = exec(buildCommand, {
      env: {
        ...process.env,
        NODE_ENV: env,
        VITE_SKIP_SOURCEMAP: skipSourcemap ? 'true' : 'false',
        VITE_MINIFY: minify ? 'true' : 'false'
      }
    });
    
    // 监听构建输出
    buildProcess.stdout.on('data', (data) => {
      const log = data.toString().trim();
      if (log) {
        logger.info(`[${appName}] ${log}`);
        if (buildNamespace) {
          buildNamespace.to(buildId).emit('buildLog', {
            buildId,
            appName,
            log,
            level: 'info',
            timestamp: chinaNow()
          });
        }
      }
    });
    
    buildProcess.stderr.on('data', (data) => {
      const log = data.toString().trim();
      if (log) {
        if (log.startsWith('(!)')) {
          logger.warn(`[${appName}] ${log}`);
          if (buildNamespace) {
            buildNamespace.to(buildId).emit('buildLog', {
              buildId,
              appName,
              log,
              level: 'warning',
              timestamp: chinaNow()
            });
          }
        } else {
          logger.error(`[${appName}] ${log}`);
          if (buildNamespace) {
            buildNamespace.to(buildId).emit('buildLog', {
              buildId,
              appName,
              log,
              level: 'error',
              timestamp: chinaNow()
            });
          }
        }
      }
    });
    
    // 等待构建完成
    await new Promise((resolve, reject) => {
      buildProcess.on('close', (code) => {
        if (code === 0) {
          logger.info(`应用 ${appName} 构建成功`);
          if (buildNamespace) {
            buildNamespace.to(buildId).emit('buildComplete', {
              buildId,
              appName,
              status: 'completed',
              message: '构建成功',
              timestamp: chinaNow()
            });
          }
          resolve();
        } else {
          const error = `应用 ${appName} 构建失败，退出码: ${code}`;
          logger.error(error);
          if (buildNamespace) {
            buildNamespace.to(buildId).emit('buildComplete', {
              buildId,
              appName,
              status: 'failed',
              message: error,
              timestamp: chinaNow()
            });
          }
          reject(new Error(error));
        }
      });
    });
  } catch (error) {
    logger.error(`构建应用 ${appName} 失败:`, error);
    if (buildNamespace) {
      buildNamespace.to(buildId).emit('buildError', {
        buildId,
        appName,
        error: error.message,
        timestamp: chinaNow()
      });
    }
  }
}

/**
 * 获取文件夹大小
 */
function getFolderSize(folderPath) {
  if (!fs.existsSync(folderPath)) {
    return '0 B';
  }
  
  const getSize = (dirPath) => {
    let size = 0;
    const files = fs.readdirSync(dirPath);
    
    for (const file of files) {
      const filePath = path.join(dirPath, file);
      const stats = fs.statSync(filePath);
      
      if (stats.isFile()) {
        size += stats.size;
      } else if (stats.isDirectory()) {
        size += getSize(filePath);
      }
    }
    
    return size;
  };
  
  const bytes = getSize(folderPath);
  
  if (bytes === 0) {
    return '0 B';
  }
  
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  
  return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${units[i]}`;
}

module.exports = router; 